#include "App.h"
#include "USART0.h"
#include "protocol.h"

/***				
							帧头      命令位   数据长度    数据位         	校验位   帧尾
字节数： 			 2					1				  1					   2						   1       1
当前位置 	 0xAA 0xAA     0xF0      0x02     0x80    0x90  	   待定    0xBB
PID				 0xAA 0xAA	   0xE0	     待定     type(1)	P/I/D(4)  	1	       1
***/
void USART0_on_byte_recv(uint8_t data){
    Protocol_recv_byte(data);
    Protocol_task();
}


void USART0_on_recv(uint8_t *data, uint32_t len){
       //printf("recv[%d]:%s\n", len, data);
//       Protocol_recv_arr(data,len);
//       Protocol_task();
}

//解析完成，把结果返回给调用者
void on_data_parsed(uint8_t* data, uint32_t len) {
    uint8_t com = data[0];
    if (com == 0xF0)
    {
        target = (int)(data[2] << 8 | data[3]);
    }
    else if (com == 0xE0)
    {   
			  uint8_t type=data[2];
        float val = bytesToFloat(&data[3],1);
        switch (type)
        {
        case 0x00: kp = val; break;
        case 0x01: ki = val; break;
        case 0x02: kd = val; break;
        default:break;
        }
    }

}


/*** 
// 发送当前位置数据
			   帧头       命令位   数据长度  数据位Current  校验位   帧尾
字节数：  2						1					1							2						1      1
       0xAA 0xAA     0xB0      0x02     0x80 0x90       待定    0xBB
校验位的计算方式通常是对前面所有字节（包括命令位、数据长度和数据位）
进行特定算法的运算得到的。
常见的校验算法有校验和（Checksum）和循环冗余校验（CRC）。
***/
static void sensor_send_data(int current)
{  
	uint8_t data[8];
	Protocol_gen_current(current,data,8);
	USART0_send_data(data,sizeof(data));
}

// 发送PID
typedef struct
{
    float kp;
    float ki;
    float kd;
} PidData;

typedef union
{
    PidData pid_data;
    uint8_t byte_buff[12];
} PID_t;

/***
【发送】pid参数
			   帧头       命令位   数据长度  数据位PID  校验位   帧尾
字节数：  2						1					1					12				1      1
       0xAA 0xAA     0xB0      0x0C              待定    0xBB
***/
static void Pid_Send_Date(float kp, float ki, float kd)
{
    // 通过联合体实现float数据转换
    PID_t pid;
    pid.pid_data.kp = kp;
    pid.pid_data.ki = ki;
    pid.pid_data.kd = kd;
    uint8_t buffDate[18];
	 
    Protocol_gen_pid(pid.byte_buff,buffDate,18);
  	USART0_send_data(buffDate,sizeof(buffDate));
}

void App_agreement_init(void)
{   
	  Protocol_init();
    Pid_Send_Date(kp, ki, kd);
}


void App_agreement_I2C_task1(void)
{  
    // 发送当前位置
    sensor_send_data(current);
}

void App_agreement_I2C_task2(void)
{   
    // 发送PID参数
    Pid_Send_Date(kp, ki, kd);
}
